package com.metalrain.alm.service;

import android.util.Log;
import com.metalrain.alm.AndroidLightManagerApplication;
import com.philips.lighting.hue.sdk.*;
import com.philips.lighting.model.PHBridge;
import com.philips.lighting.model.PHGroup;
import com.philips.lighting.model.PHLight;
import com.philips.lighting.model.PHLightState;

import java.util.*;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

/**
 * Created by administrator on 2014-06-08.
 */
public class HueManager {

    final LCA_Service service;
    public PHHueSDK phHueSDK = PHHueSDK.create();
    public PHSDKListener listener = new MyPHSDKListener(this);
    private final Executor executor = Executors.newFixedThreadPool(16);

    public int getGroupAndLightCount() {

        PHBridge bridge = phHueSDK.getSelectedBridge();
        if (bridge != null) {
            List<PHGroup> groups = bridge.getResourceCache().getAllGroups();
            List<PHLight> lights = bridge.getResourceCache().getAllLights();
            int count = groups.size();
            for (PHLight light:lights) {
                if (lightNotInGroups(light, groups)) {
                    count ++;
                }
            }

            Log.i("HueManager", "getGroupAndLightCount: " + count);
            return count;
        }
        Log.i("HueManager", "getGroupAndLightCount: 0");
        return 0;
    }

    /**
     * Gets the PHGroup or PHLight that should map to the list. Groups first, Lights after
     * @param pos
     * @return
     */
    public Object getGroupOrLight(int pos) {
        PHBridge bridge = phHueSDK.getSelectedBridge();
        if (bridge != null) {
            List<PHGroup> groups = bridge.getResourceCache().getAllGroups();
            if (pos < groups.size()) {
                return groups.get(pos);
            } else {
                pos -= groups.size();
                List<PHLight> lights = bridge.getResourceCache().getAllLights();

                Collections.sort(lights, new Comparator<PHLight>() {
                    @Override
                    public int compare(PHLight phLight, PHLight phLight2) {
                        return phLight.getName().compareTo(phLight2.getName());
                    }
                });


                if (pos < lights.size()) {
                    return lights.get(pos);
                }
                throw new ArrayIndexOutOfBoundsException("Pos is too high, can't find the light or group");
            }
        }
        return null;

    }

    private boolean lightNotInGroups(PHLight light, List<PHGroup> groups) {
        if (light == null) throw new IllegalArgumentException("Light can not be null");
        if (groups == null) throw new IllegalArgumentException();
        for (PHGroup group:groups) {
            for (String id:group.getLightIdentifiers()) {
                if (id.equals(light.getIdentifier())) {
                    return false;
                }
            }
        }
        return true;
    }


    public HueManager(LCA_Service camHueService) {
        this.service = camHueService;
        phHueSDK.getNotificationManager().registerSDKListener(listener);
    }

    public void findHue() {
        PHBridgeSearchManager sm = (PHBridgeSearchManager) phHueSDK.getSDKService(PHHueSDK.SEARCH_BRIDGE);
        sm.search(true, true);

    }


    public void togglePower(final PHLight light, boolean similar) {
        executor.execute(new Runnable() {
            @Override
            public void run() {
                PHLightState lightState = new PHLightState();
                lightState.setColorMode(PHLight.PHLightColorMode.COLORMODE_HUE_SATURATION);
                if (light.getLastKnownLightState().isOn()) {
                    lightState.setOn(false);
                } else {
                    lightState.setOn(true);
                }
                phHueSDK.getSelectedBridge().updateLightState(light, lightState);
            }
        });
    }

    public void randLight(final PHLight light, boolean similarLights) {
        if (!similarLights) {
            randLight(light);
        } else {
            String start = light.getName().split(" ")[0];
            for (PHLight light2 : this.phHueSDK.getSelectedBridge().getResourceCache().getAllLights()) {
                if ( light2.getName().contains(start) ) {
                    randLight(light2);
                }
            }
        }
    }


    public void randLight(final PHLight light) {
        executor.execute(new Runnable() {
            @Override
            public void run() {
                Log.i("LightGroupsFragment", "PHLightHandling");
                PHLightState state = new PHLightState();
                state.setOn(true);
                state.setColorMode(PHLight.PHLightColorMode.COLORMODE_HUE_SATURATION);
                state.setHue((int) (Math.random() * 60000));
                state.setBrightness(250);
                state.setSaturation(250);
                AndroidLightManagerApplication.getLcaService().mHueManager.phHueSDK.getSelectedBridge().updateLightState(light, state);
            }
        });
    }

    public void warmLight(final PHLight light, boolean similarLights) {
        if (!similarLights) {
            warmLight(light);
        } else {
            String start = light.getName().split(" ")[0];
            for (PHLight light2 : this.phHueSDK.getSelectedBridge().getResourceCache().getAllLights()) {
                if ( light2.getName().contains(start) ) {
                    warmLight(light2);
                }
            }
        }
    }

    public void warmLight(final PHLight light) {
        executor.execute(new Runnable() {
            @Override
            public void run() {
                Log.i("LightGroupsFragment", "PHLightHandling");
                PHLightState state = new PHLightState();
                state.setOn(true);
                state.setColorMode(PHLight.PHLightColorMode.COLORMODE_CT);
                state.setCt(500);
                state.setBrightness(250);
                AndroidLightManagerApplication.getLcaService().mHueManager.phHueSDK.getSelectedBridge().updateLightState(light, state);
            }
        });
    }

    public void coldLight(final PHLight light, boolean similarLights) {
        if (!similarLights) {
            coldLight(light);
        } else {
            String start = light.getName().split(" ")[0];
            for (PHLight light2 : this.phHueSDK.getSelectedBridge().getResourceCache().getAllLights()) {
                if ( light2.getName().contains(start) ) {
                    coldLight(light2);
                }
            }
        }
    }
    public void coldLight(final PHLight light) {
        executor.execute(new Runnable() {
            @Override
            public void run() {
                Log.i("LightGroupsFragment", "PHLightHandling");
                PHLightState state = new PHLightState();
                state.setOn(true);
                state.setColorMode(PHLight.PHLightColorMode.COLORMODE_CT);
                state.setCt(205);
                state.setBrightness(250);
                AndroidLightManagerApplication.getLcaService().mHueManager.phHueSDK.getSelectedBridge().updateLightState(light, state);
            }
        });
    }

    public void adjustBrightness(final PHLight light, final int i, boolean similar) {
        if (!similar) {
            adjustBrightness(light,i);
        } else {
            String start = light.getName().split(" ")[0];
            for (PHLight light2 : this.phHueSDK.getSelectedBridge().getResourceCache().getAllLights()) {
                if ( light2.getName().contains(start) ) {
                    adjustBrightness(light2,i);
                }
            }
        }
    }
    public void adjustBrightness(final PHLight light, final int i) {
        executor.execute(new Runnable() {
            @Override
            public void run() {
                Log.i("LightGroupsFragment", "adjustBrightness");

                PHLightState state = light.getLastKnownLightState();
                int brightness = state.getBrightness();
                brightness += i;
                if (brightness > 255) brightness = 255;
                if (brightness < 0) brightness = 0;
                state.setBrightness(brightness);
                AndroidLightManagerApplication.getLcaService().mHueManager.phHueSDK.getSelectedBridge().updateLightState(light, state);
            }
        });

    }

    public void randAllLights() {
        for (PHLight light:this.phHueSDK.getSelectedBridge().getResourceCache().getAllLights()) {
            randLight(light, false);
        }
    }

    public void warmAll() {
        for (PHLight light:this.phHueSDK.getSelectedBridge().getResourceCache().getAllLights()) {
            warmLight(light, false);
        }
    }

    public void coldAll() {
        for (PHLight light:this.phHueSDK.getSelectedBridge().getResourceCache().getAllLights()) {
            coldLight(light, false);
        }
    }

    public void turnOffAllLights() {
        for (final PHLight light:this.phHueSDK.getSelectedBridge().getResourceCache().getAllLights()) {
            executor.execute(new Runnable() {
                @Override
                public void run() {
                    PHLightState state = light.getLastKnownLightState();
                    state.setOn(false);
                    phHueSDK.getSelectedBridge().updateLightState(light, state);
                }
            });
        }

    }

    public void adjustAllBrightness(int i) {
        for (PHLight light:this.phHueSDK.getSelectedBridge().getResourceCache().getAllLights()) {
            adjustBrightness(light, i, false);
        }
    }
}
